package com.clinic.logic.drug;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.clinic.accessor.db.DrugAccessor;
import com.clinic.accessor.db.DrugIssueAccessor;
import com.clinic.accessor.db.DrugStockAccessor;
import com.clinic.entity.db.Drug;
import com.clinic.entity.db.DrugIssue;
import com.clinic.entity.db.DrugStock;
import com.clinic.entity.gui.GuiDrugStock;
import com.clinic.entity.gui.GuiPagination;
import com.clinic.entity.param.Index;
import com.clinic.util.CommonUtil;
import com.clinic.util.ConvertUtil;

@Component
public class DrugStockLogic {

	@Autowired
	private DrugStockAccessor drugStockAccessor;
	@Autowired
	private DrugAccessor drugAccessor;
	@Autowired
	private DrugIssueAccessor drugIssueAccessor;
	
	@Transactional
	public GuiDrugStock getDrugStockById(long id){
		DrugStock drugStock = drugStockAccessor.getDrugStockById(id);
		return ConvertUtil.getGuiDrugStockByDrugStock(drugStock);
	}
	
	public GuiDrugStock insertDrugStock(GuiDrugStock guiDrugStock){
		DrugStock drugStock = new DrugStock();
		drugStock.setExpireDate(guiDrugStock.getExpireDate());
		drugStock.setOrderAmount(guiDrugStock.getOrderAmount());
		drugStock.setStockAmount(guiDrugStock.getOrderAmount()); // initial stock amount same to order amount
		Drug drug = drugAccessor.getDrugById(guiDrugStock.getDrug().getDrugId());
		drugStock.setDrug(drug);
		DrugStock iDrugStock = drugStockAccessor.insertOrUpdate(drugStock);
		return ConvertUtil.getGuiDrugStockByDrugStock(iDrugStock);
	}
	
	/*public boolean isNotValidDrugStockInsert(GuiDrugStock guiDrugStock) {
		
		return !isValidDrugStockInsert(guiDrugStock);
	}
	
	public boolean isValidDrugStockInsert(GuiDrugStock guiDrugStock) {
		DrugStock drugstock = drugStockAccessor.getDrugStockByDrugId(guiDrugStock.getDrug().getDrugId());
		return (drugstock == null);	
	}*/
	
	public boolean isValidDate(GuiDrugStock guiDrugStock) {
		/*boolean validDrugStock = isValidDrugStockInsert(guiDrugStock);
		if(validDrugStock == true) {
			Date date = guiDrugStock.getExpireDate();
			
			boolean validDate = false;
			int daysLeft = CommonUtil.getDaysLeftfromToday(date);
			if(daysLeft > 0){
				validDate = true;
			}  
			return validDate;
		}*/
		Date date = guiDrugStock.getExpireDate();
		
		boolean validDate = false;
		int daysLeft = CommonUtil.getDaysLeftfromToday(date);
		if(daysLeft > 0){
			validDate = true;
		}  
		return validDate;
	}
	
	@Transactional
	public GuiDrugStock updateDrugStock(GuiDrugStock guiDrugStock){
		DrugStock drugStock = drugStockAccessor.getDrugStockById(guiDrugStock.getDrugStockId());
		
		List<DrugIssue> result = new ArrayList<>(drugStock.getDrugIssues()); 
		
		int count = 0;
		for(DrugIssue drugIssue : result){
			count += drugIssue.getAmount();
		}
		
		int uOrderAmount = guiDrugStock.getOrderAmount(); 
		int updateStockAmount = uOrderAmount - count;
		
		drugStock.setExpireDate(guiDrugStock.getExpireDate());
		drugStock.setOrderAmount(guiDrugStock.getOrderAmount());
		drugStock.setStockAmount(updateStockAmount);
		Drug drug = drugAccessor.getDrugById(guiDrugStock.getDrug().getDrugId());
		drugStock.setDrug(drug);
		DrugStock iDrugStock = drugStockAccessor.insertOrUpdate(drugStock);
		return ConvertUtil.getGuiDrugStockByDrugStock(iDrugStock);
	}
	
	/*@Transactional
	public boolean isValidDrugStockUpdate(GuiDrugStock guiDrugStock) {
		long nDrugId = guiDrugStock.getDrug().getDrugId();
		DrugStock oStock = drugStockAccessor.getDrugStockById(guiDrugStock.getDrugStockId());
		long oDrugId = oStock.getDrug().getDrugId();
		DrugStock uStock = drugStockAccessor.getDrugStockByDrugId(nDrugId);
		
		if(nDrugId == oDrugId) {
			return true;
		} else {
			return uStock == null;
		} 
	}*/
	
	public boolean isDrugEmpty(GuiDrugStock guiDrugStock) {
		return (guiDrugStock.getDrug().getDrugId() < 0);
	}
	
	public boolean isOrderAmountEmpty(GuiDrugStock guiDrugStock) {
		return (guiDrugStock.getOrderAmount() < 0);
	}
	
	public boolean isStockAmountEmpty(GuiDrugStock guiDrugStock) {
		return (guiDrugStock.getStockAmount() < 0);
	}
	
	public boolean isExpireDateEmpty(GuiDrugStock guiDrugStock) {
		return StringUtils.isBlank(guiDrugStock.getExpireDateString());
	}
	
	public boolean isValidExpireDate(GuiDrugStock guiDrugStock) {
		Date expireDate = guiDrugStock.getExpireDate();
		int daysLeft = CommonUtil.getDaysLeftfromToday(expireDate);
		return (daysLeft > 0);
	}
	
	public void deleteDrugStockDetailsById(long id) {
		DrugStock drugstock = drugStockAccessor.getDrugStockById(id);
		if (drugstock != null) {
			// TODO delete other related data before ... appointments, contacts... etc
			drugstock.setDrug(null);
			drugStockAccessor.delete(drugstock);
		}
	}
	
	@Transactional
	public List<GuiDrugStock> getDrugStocksByDrugId(long drugId, Index index){
		List<GuiDrugStock> result = new ArrayList<>();
		List<DrugStock> drugStocks = drugStockAccessor.getDrugStocksByDrugId(drugId, index);
		for (DrugStock drugStock : drugStocks) {
			result.add(ConvertUtil.getGuiDrugStockByDrugStock(drugStock));
		}
		return result;
	}
	
	public GuiPagination getPaginationOfDrugStocksByDrugId(long drugId, int page) {
		int total = drugStockAccessor.countDrugStockByDrugId(drugId);
		return CommonUtil.getPaginationInfo(page, total);
	}
	
	@Transactional
	public List<GuiDrugStock> getDrugStocksByTerm(String term, String column, Index index) {
		List<GuiDrugStock> result = new ArrayList<>();
		List<DrugStock> drugStocks = drugStockAccessor.getDrugStocksByTerm(term, column, index);
		for (DrugStock drugStock : drugStocks) {
			result.add(ConvertUtil.getGuiDrugStockByDrugStock(drugStock));
		}
		return result;
	}
	
	public List<GuiDrugStock> getStockAvailableDrugStockList(List<GuiDrugStock> guiDrugStockList) {
		List<GuiDrugStock> result = new ArrayList<>();
		for(GuiDrugStock guiDrugStock : guiDrugStockList) {
			if(guiDrugStock.getStockAmount() > 0){
				result.add(guiDrugStock);
			}
		}
		return result;
	}
	
	@Transactional
	public List<GuiDrugStock> getOutDatedDrugStocksByDate(Date date, Index index) {
		List<GuiDrugStock> result = new ArrayList<>();
		List<DrugStock> drugStocks = drugStockAccessor.getOutDatedDrugStocksByDate(date, index);
		for (DrugStock drugStock : drugStocks) {
			result.add(ConvertUtil.getGuiDrugStockByDrugStock(drugStock));
		}
		return result;
	}
	
	@Transactional
	public List<GuiDrugStock> getToBeExpiredDrugStocksByDate(Date date, Index index) {
		List<GuiDrugStock> result = new ArrayList<>();
		List<DrugStock> drugStocks = drugStockAccessor.getOutDatedDrugStocksByDate(date, index);
		for (DrugStock drugStock : drugStocks) {
			result.add(ConvertUtil.getGuiDrugStockByDrugStock(drugStock));
		}
		return result;
	}
	
	public GuiPagination getPaginationOfDrugStocksByTerm(String term, int page) {
		int total = drugStockAccessor.countDrugStocksByTerm(term);
		return CommonUtil.getPaginationInfo(page, total);
	}

	@Transactional
	public List<GuiDrugStock> getDrugStocks(Index index) {
		List<GuiDrugStock> result = new ArrayList<>();
		List<DrugStock> drugStocks = drugStockAccessor.getDrugStocks(index);
		for (DrugStock drugStock : drugStocks) {
			result.add(ConvertUtil.getGuiDrugStockByDrugStock(drugStock));
		}
		return result;
	}
	
	public GuiPagination getPaginationOfDrugStocks(int page) {		
		int total = drugStockAccessor.countDrugStocks();
		return CommonUtil.getPaginationInfo(page, total);
	}
}
